# -*- python -*-
# ex: set syntax=python:

# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This is the buildmaster config file for the 'nacl' bot. It must
# be installed as 'master.cfg' in your buildmaster's base directory
# (although the filename can be changed with the --basedir option to
# 'mktap buildbot master').

# It has one job: define a dictionary named BuildmasterConfig. This
# dictionary has a variety of keys to control different aspects of the
# buildmaster. They are documented in docs/config.xhtml .


from buildbot.scheduler import Nightly
from buildbot.scheduler import Scheduler

from common import chromium_utils

from master import build_utils
from master import gitiles_poller
from master import master_utils
from master import slaves_list
from master.factory import nacl_ports_factory

import config
import master_site_config

ActiveMaster = master_site_config.NativeClientPorts

GOOD_REVISIONS = ActiveMaster.is_production_host

# This is the dictionary that the buildmaster pays attention to. We also use
# a shorter alias to save typing.
c = BuildmasterConfig = {}

config.DatabaseSetup(c, require_dbconfig=ActiveMaster.is_production_host)

####### CHANGESOURCES

# the 'change_source' list tells the buildmaster how it should find out about
# source code changes. Any class which implements IChangeSource can be added
# to this list: there are several in buildbot/changes/*.py to choose from.

git_url = 'https://chromium.googlesource.com/external/naclports.git'
poller = gitiles_poller.GitilesPoller(git_url)
c['change_source'] = [poller]

####### BUILDERS

# buildbot/process/factory.py provides several BuildFactory classes you can
# start with, which implement build processes for common targets (GNU
# autoconf projects, CPAN perl modules, etc). The factory.BuildFactory is the
# base class, and is configured with a series of BuildSteps. When the build
# is run, the appropriate buildslave is told to execute each Step in turn.

# the first BuildStep is typically responsible for obtaining a copy of the
# sources. There are source-obtaining Steps in buildbot/process/step.py for
# CVS, SVN, and others.


# ----------------------------------------------------------------------------
# FACTORIES

m_posix = nacl_ports_factory.NativeClientPortsFactory(
    build_dir='native_client_ports',
    name='src',
    alternate_url=git_url,
    target_platform='linux2')

# Some shortcut to simplify the code below.
F_POSIX = m_posix.NativeClientPortsFactory


# The identifier of the factory is the build configuration. If two factories
# are using the same build configuration, they should have the same identifier.

# BuilderTesters using a custom build configuration.
factories = []

shards = {
  'linux': {
    'newlib': 5,
    'glibc': 5,
    'pnacl': 5,
    'clang': 5,
    'bionic': 1,
    'emscripten': 1,
  },
  'mac': {
    'newlib': 2,
    'glibc': 2,
    'pnacl': 2,
    'clang': 2,
    'bionic': 0,
    'emscripten': 0,
  },
}
platforms = sorted(shards.keys())
libcs = sorted(shards[platforms[0]].keys())

# no_gclient_branch means that gclient will use --revision=<SHA> rather
# than the default --revision=<branch>@<SHA>
factory_properties = {'no_gclient_branch': True}

for when in ['', 'nightly-']:
  for platform in platforms:
    for index, libc in enumerate(libcs):
      order = {'': index, 'nightly-': index + len(libcs)}[when]
      for shard in range(shards[platform][libc]):
        factories.append(['%s%s-%s-%d' % (when, platform, libc, shard),
                          '%02d%s%s' % (order, when, libc),
                          platform,
                          F_POSIX(factory_properties=factory_properties)])

# SDK builder
factories.append(['linux-sdk', '99sdk', 'linux', F_POSIX()])

all_builders = [f[0] for f in factories]
checkin_builders = [b for b in all_builders if not b.startswith('nightly-')]
nightly_builders = [b for b in all_builders if b.startswith('nightly-')]


####### SCHEDULERS
## configure the Schedulers
# Main scheduler for all changes in trunk.
s_checkin = Scheduler(
   name='checkin',
   branch='master',
   treeStableTimer=60,
   builderNames=checkin_builders,
)
# Nightly scheduler Main scheduler for all changes in trunk.
s_nightly = Nightly(
   name='nightly',
   branch='master',
   hour=3, minute=15,  # 3:15am PST
   builderNames=nightly_builders,
)
c['schedulers'] = [s_checkin, s_nightly]


c['builders'] = []
slaves = slaves_list.SlavesList('slaves.cfg', 'NativeClientPorts')
for buildername, category, platform, factory in factories:
  c['builders'].append({
      'name': buildername,
      'slavenames': slaves.GetSlavesName(builder=platform),
      'builddir': buildername,
      'slavebuilddir': 'naclports',
      'factory': factory,
      'category': '%s|full' % category,
      'auto_reboot': ActiveMaster.is_production_host,
  })


####### BUILDSLAVES

# The 'slaves' list defines the set of allowable buildslaves. List all the
# slaves registered to a builder. Remove dupes.
c['slaves'] = master_utils.AutoSetupSlaves(c['builders'],
                                           config.Master.GetBotPassword())


####### STATUS TARGETS

# Buildbot master url:
# Must come before AutoSetupMaster().
c['buildbotURL'] = ActiveMaster.buildbot_url

# Adds common status and tools to this master.
master_utils.AutoSetupMaster(c, ActiveMaster,
                             tagComparator=poller.comparator,
                             mail_notifier=True,
                             public_html='../master.chromium/public_html',
                             templates=['./templates',
                                        '../master.client.nacl/templates'])


# Adjust the buildCaches to be 3x the number of slaves per builder.
c['autoBuildCacheRatio'] = 3
